/*
 * Copyright 2002 Sun Microsystems, Inc. All rights reserved.
 * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
 */

/*
 * @(#)ConnectionClient1.java	1.12 02/01/12
 */

package jdbcts.connection;

import java.io.*;
import java.util.*;
import java.math.*;

import java.sql.*;
import javax.sql.*;

import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;

import com.sun.cts.util.*;
import com.sun.cts.porting.*;
import com.sun.cts.harness.*;

import java.rmi.RemoteException;

import javasoft.sqe.javatest.Status;
import jdbcts.SuperTest;
import jdbcts.common.DataSourceConnection;
import jdbcts.common.DriverManagerConnection;
import jdbcts.common.dbSchema;
import jdbcts.common.rsSchema;

import com.sun.cts.tests.jdbc.ee.common.*;

// Merant DataSource class
//import com.merant.sequelink.jdbcx.datasource.*;


/**
 * The ConnectionClient1 class tests methods of Connection interface using 
 * Sun's J2EE Reference Implementation.
 * @author  
 * @version 1.7, 06/16/99
 */

public class ConnectionClient1 extends SuperTest implements Serializable
{
	private static final String testName = "jdbc.ee.connection.connection1";

	//Naming specific member variables
	private CTSNamingContextInterface jc = null;

	//Harness requirements 

	private transient static Connection conn = null;
	private ResultSet rs=null;
	private static Statement stmt=null;
	private transient static DatabaseMetaData dbmd=null;
	private DataSource ds1 = null;
	private static dbSchema dbSch=null;
	private static rsSchema rsSch=null;
	private static	String drManager=null;
	private Properties props = null;
	private String sVehicle = null;

	/* Run test in standalone mode */
//	public static void main(String[] args) 
//	{
//		ConnectionClient1 theTests = new ConnectionClient1();
//		Status s=theTests.run(args, System.out, System.err);
//		s.exit();
//	}

	/*  Test setup: */
	/*
	 *   @class.setup_props: Driver, the Driver name;
	 *			db1, the database name with url;
	 *			user1, the database user name;
	 *			password1, the database password;
	 *			db2, the database name with url;
	 *			user2, the database user name;
	 *			password2, the database password;
	 *			DriverManager, flag for DriverManager;
	 *			ptable, the primary table;
	 *			ftable, the foreign table;
	 *			cofSize, the initial size of the ptable;
	 *			cofTypeSize, the initial size of the ftable;
	 *			binarySize, size of binary data type;
	 *			varbinarySize, size of varbinary data type;
	 *			longvarbinarySize, size of longvarbinary data type;
	 *  @class.testArgs:     -ap ctssql.stmt
	 */
	@BeforeClass
//	public void setup(String[] args, Properties p) throws Exception
	public static void setup() throws Exception
	{
		try
		{
			try
			{
//				drManager = p.getProperty("DriverManager","");
			    drManager = isDRManager;
//				sVehicle = p.getProperty("vehicle");
				if (drManager.length() == 0)
					throw new Exception("Invalid DriverManager Name");
//				props=p;

				if(drManager.equals("yes"))
				{
					logMsg("Using DriverManager");
					DriverManagerConnection dmCon = new DriverManagerConnection();
					conn = dmCon.getConnection(null);
				}
				else
				{
					logMsg("Using DataSource");
					DataSourceConnection dsCon = new DataSourceConnection();
//					conn = dsCon.getConnection(p);
					conn = dsCon.getConnection(null);
				}
				stmt=conn.createStatement();
				dbSch=new dbSchema();
//				dbSch.createData(p,conn);
				dbmd=conn.getMetaData();
				rsSch=new rsSchema();
				
			}
			catch (SQLException ex)
			{
				logErr("SQL Exception : " + ex.getMessage());
			}
		}
		catch (Exception e ) 
		{
			logErr("Setup Failed!");
			TestUtil.printStackTrace(e);
		}
	}



	/*
	 * @testName:         testClose
	 *                    
	 * @assertion:        A Connection object represents a Connection in a database.  
	 *                    A Connection session includes the SQL Statements that are 
	 *                    executed and the results that are returned over that connection.
	 *                    (See section 11.1 of JDBC 2.0 API Reference & Tutorial second 
	 *                    edition). 
	 *                    
	 *                    The JDBC drivers must provide accurate and complete 
	 *                    metadata through the Connection.getMetaData() method. (See 
	 *                    section 6.2.2.3 Java2 Platform Enterprise Edition (J2EE) 
	 *                    specification v1.2).  
	 *                    
	 *                    The Close method closes the connection object and the close()
	 *                    method does not return any value. (See JDK 1.2.2 API
	 *                    documentation)
	 *
	 * @test_Strategy:    Get a Connection object and call close() method
	 *                    and call isClosed() method and it should return a true value
	 *
	 */
	@Test
	public void testClose() throws Exception 
	{
		boolean closeFlag=false;
		Connection con=null;
		try
		{
//			if(drManager.equals("yes"))
//			{
				DriverManagerConnection dmCon = new DriverManagerConnection();
//				con = dmCon.getConnection(props);
				con = dmCon.getConnection(null);
//			}
//			else 
//			{
//				DataSourceConnection dsCon = new DataSourceConnection();
//				con = dsCon.getConnection(props);
//			}
			
			// invoking the close method
			logMsg("Calling Close() method ");
			con.close();
			
			closeFlag= con.isClosed();
			
			if (closeFlag)
			{
				logMsg("close method closes the Connection object ");
			}
			else
			{
				logErr("close method does not close the Connection object");
				throw new Exception("Call to Close is Failed!");
			}
		}
		catch (SQLException sqle)
		{
			logErr("SQL Exception " + sqle.getMessage());
			throw new Exception("Call to Close is Failed!");
		}
		catch (Exception e) 
		{
			logErr("Unexpected Exception " + e.getMessage());
			throw new Exception("Call to Close is Failed!", e);
		}
	}


	/*
	 * @testName:         testCreateStatement01
	 *                    
	 * @assertion:        A Connection object represents a Connection in a database.  
	 *                    A Connection session includes the SQL Statements that are 
	 *                    executed and the results that are returned over that connection.
	 *                    (See section 11.1 of JDBC 2.0 API Reference & Tutorial second 
	 *                    edition).  
	 *                    
	 *                    The JDBC drivers must provide accurate and complete 
	 *                    metadata through the Connection.getMetaData() method. (See 
	 *                    section 6.2.2.3 Java2 Platform Enterprise Edition (J2EE) 
	 *                    specification v1.2).  
	 *                    
	 *                    The createStatement() method returns  a Statement object that 
	 *                    will produce non-scrollable and non-updatable result set. 
	 *                    (See JDK 1.2.2 API documentation)
	 *
	 * @test_Strategy:    Get a Connection object and call createStatement()
	 *                    method and call instanceof to check 
	 *                    It should return a Statement object
	 */
	@Test
	public void testCreateStatement01() throws Exception 
	{
		Statement statemt=null;
		try
		{
			// invoking the createStatement method
			logMsg("Calling createStatement() method ");
			statemt=conn.createStatement();
			
			
			if (statemt instanceof Statement)
			{
				logMsg("createStatement method creates a Statement object");
			}
			else
			{
				logErr("createStatement method does not create a Statement object");
				throw new Exception("Call to createStatement is Failed!");
			}
			statemt.close();
		}
		catch (SQLException sqle)
		{
			logErr("SQL Exception " + sqle.getMessage());
			throw new Exception("Call to createStatement is Failed!");
		}
		catch (Exception e) 
		{
			logErr("Unexpected Exception " + e.getMessage());
			throw new Exception("Call to createStatement is Failed!", e);
		}
	}



	/*
	 * @testName:         testGetCatalog
	 *                    
	 * @assertion:        A Connection object represents a Connection in a database.  
	 *                    A Connection session includes the SQL Statements that are 
	 *                    executed and the results that are returned over that connection.
	 *                    (See section 11.1 of JDBC 2.0 API Reference & Tutorial second 
	 *                    edition)
	 *                    
	 *                    The JDBC drivers must provide accurate and complete 
	 *                    metadata through the Connection.getMetaData() method. (See 
	 *                    section 6.2.2.3 Java2 Platform Enterprise Edition (J2EE) 
	 *                    specification v1.2)
	 *                    
	 *                    The getCatalog() method returns a String object; the string 
	 *                    represents the connection object's catalog name and null if there 
	 *                    is none.  (See JDK 1.2.2 API documentation)
	 *                    
	 * @test_Strategy:    Get a Connection object and call getCatalog() method
	 *                    It should return a String value The getCatalogs() method in
	 *                    Databasemeta data object will return a Resultset object that contains
	 *                    the catalog name in the column TABLE_CAT .The String returned by
	 *                    Connection.getCatalog() method will be checked against these 
	 *                    column values.
	 */
	@Test
	public void testGetCatalog() throws Exception 
	{
		String catalogName = null;
		String url=null;
		String retValue = null;
		String extValue = null ;
		boolean flag = false;
		try
		{
		
			// to retrieve the database from the URL of the propertyFile
			logMsg("Calling getCatalog() method ");
			retValue=conn.getCatalog();
			
			logMsg("Catalog Name   " + retValue);
			
			if(retValue != null)
			{
				ResultSet rs = dbmd.getCatalogs();
				
				while(rs.next())
				{
					extValue = rs.getString("TABLE_CAT");
					logMsg("Catalog Name   " + extValue);
					if(retValue.equals(extValue))
					{
						flag= true;
						break;
					}
				}
				if(flag)
				{
					logMsg("getCatalog returns the Catalog name" + retValue);
				}
				else
				{
					logErr("getCatalog does not return the catalog name");
					throw new Exception("Call to getCatalog is Failed!");
				}
			}
			else
			{
				logMsg("getCatalog returns a null String Object");
			}
		}
		catch (SQLException sqle)
		{
			logErr("SQL Exception " + sqle.getMessage());
			throw new Exception("Call to getCatalog is Failed!");
		}
		catch (Exception e) 
		{
			logErr("Unexpected Exception " + e.getMessage());
			throw new Exception("Call to getCatalog is Failed!", e);
		}
	}


	/*
	 * @testName:         testGetMetaData
	 *                    
	 * @assertion:        A Connection object represents a Connection in a database.  
	 *                    A Connection session includes the SQL Statements that are 
	 *                    executed and the results that are returned over that connection.
	 *                    (See section 11.1 of JDBC 2.0 API Reference & Tutorial second 
	 *                    edition)
	 *                    
	 *                    The JDBC drivers must provide accurate and complete 
	 *                    metadata through the Connection.getMetaData() method. (See 
	 *                    section 6.2.2.3 Java2 Platform Enterprise Edition (J2EE) 
	 *                    specification v1.2)
	 *                    
	 *                    The getMetaData method returns a DatabaseMetaData object.
	 *                    (See JDK 1.2.2 API documentation)
	 *
	 * @test_Strategy:    Get a Connection object and call getMetaData()
	 *                    method and call instanceof method to check 
	 *                    It should return a DatabaseMetaData object
	 *
	 */
	@Test
	public void testGetMetaData() throws Exception 
	{
		DatabaseMetaData rsmd=null;
		try
		{
			// invoking the getMetaData method
			logMsg("Calling getMetaData() method ");
			rsmd=conn.getMetaData();
			
			if (rsmd instanceof DatabaseMetaData)
			{
				logMsg("getMetaData returns the DatabaseMetaData object ");
			}
			else
			{
				logErr("getMetaData does not return the DatabaseMetaData object");
				throw new Exception("Call to getMetaData is Failed!");
			}
		}
		catch (SQLException sqle)
		{
			logErr("SQL Exception " + sqle.getMessage());
			throw new Exception("Call to getMetaData is Failed!");
		}
		catch (Exception e) 
		{
			logErr("Unexpected Exception " + e.getMessage());
			throw new Exception("Call to getMetaData is Failed!", e);
		}
	}


	/*
	 * @testName:         testGetTransactionIsolation
	 *                    
	 * @assertion:        A Connection object represents a Connection in a database.  
	 *                    A Connection session includes the SQL Statements that are 
	 *                    executed and the results that are returned over that connection.
	 *                    (See section 11.1 of JDBC 2.0 API Reference & Tutorial second 
	 *                    edition).  
	 *                    
	 *                    The JDBC drivers must provide accurate and complete 
	 *                    metadata through the Connection.getMetaData() method. (See 
	 *                    section 6.2.2.3 Java2 Platform Enterprise Edition (J2EE) 
	 *                    specification v1.2)
	 *                    
	 *                    The getTransactionIsolation method returns an int value and must 
	 *                    be equal to the value of  TRANSACTION_NONE or 
	 *                    TRANSACTION_READ_COMMITTED or TRANSACTION_READ_UNCOMMITTED 
	 *                    or TRANSACTION_REPEATABLE_READ or TRANSACTION_SERIALIZABLE.
	 *                    (See JDK 1.2.2 API documentation)
	 *
	 * @test_Strategy:    Get a Connection object and call getTransactionIsolation() method
	 *                    It should return a Integer value and must be equal to the value of
	 *                    TRANSACTION_NONE or TRANSACTION_READ_COMMITTED or 
	 *                    TRANSACTION_READ_UNCOMMITTED or TRANSACTION_REPEATABLE_READ or 
	 *                    TRANSACTION_SERIALIZABLE which is default set by the driver
	 * 
	 *
	 */
	@Test
	public void testGetTransactionIsolation() throws Exception 
	{
		int transIsolateVal=0;
		try
		{
			// invoking the getTransactionIsolation method
			logMsg("Calling getTransactionIsolation() method ");
			transIsolateVal=conn.getTransactionIsolation();
			
			if (transIsolateVal==Connection.TRANSACTION_NONE)
			{
				logMsg("getTransactionIsolation method returns Transaction Isolation mode as "+ transIsolateVal);
			}
			else if (transIsolateVal==Connection.TRANSACTION_READ_COMMITTED)
			{
				logMsg("getTransactionIsolation method returns Transaction Isolation mode as "+ transIsolateVal);
			}
			else if (transIsolateVal==Connection.TRANSACTION_READ_UNCOMMITTED)
			{
				logMsg("getTransactionIsolation method returns Transaction Isolation mode as "+ transIsolateVal);
			}
			else if (transIsolateVal==Connection.TRANSACTION_REPEATABLE_READ)
			{
				logMsg("getTransactionIsolation method returns Transaction Isolation mode as "+ transIsolateVal);
			}
			else if (transIsolateVal==Connection.TRANSACTION_SERIALIZABLE)
			{
				logMsg("getTransactionIsolation method returns Transaction Isolation mode as "+ transIsolateVal);
			}
			else
			{
				logErr("getTransactionIsolation method returns an invalid value");
				throw new Exception("Call to getTransactionIsolation is Failed!");
			}
		}
		catch (SQLException sqle)
		{
			logErr("SQL Exception " + sqle.getMessage());
			throw new Exception("Call to getTransactionIsolation is Failed!");
		}
		catch (Exception e) 
		{
			logErr("Unexpected Exception " + e.getMessage());
			throw new Exception("Call to getTransactionIsolation is Failed!", e);
		}
	}



	/*
	 * @testName:         testIsClosed01
	 *                    
	 * @assertion:        A Connection object represents a Connection in a database.  
	 *                    A Connection session includes the SQL Statements that are 
	 *                    executed and the results that are returned over that connection.
	 *                    (See section 11.1 of JDBC 2.0 API Reference & Tutorial second 
	 *                    edition).  
	 *                    
	 *                    The JDBC drivers must provide accurate and complete 
	 *                    metadata through the Connection.getMetaData() method. (See 
	 *                    section 6.2.2.3 Java2 Platform Enterprise Edition (J2EE) 
	 *                    specification v1.2).  
	 *                    
	 *                    The isClosed method returns a boolean value; true if the 
	 *                    connection is closed or false if it is still open.
	 *                    (See JDK 1.2.2 API documentation)
	 *
	 * @test_Strategy:    Get a Connection object and call isClosed() method
	 *                    It should return a boolean value and the value should be 
	 *                    equal to false
	 *
	 */
	@Test
	public void testIsClosed01() throws Exception 
	{
		boolean closeFlag=false;
		Connection con=null;
		try
		{
//			if(drManager.equals("yes"))
//			{
				DriverManagerConnection dmCon = new DriverManagerConnection();
				con = dmCon.getConnection(props);
//			}
//			else
//			{
//				DataSourceConnection dsCon = new DataSourceConnection();
//				con = dsCon.getConnection(props);
//			}
			
			logMsg("Calling isClosed Method");
			closeFlag= con.isClosed();
			
			if (!closeFlag)
			{
				logMsg("isClosed method returns  "+ closeFlag);
			}
			else
			{
				logErr("isClosed method returns an invalid value");
				throw new Exception("Call to isClosed is Failed!");
			}
			con.close();
		}
		catch (SQLException sqle)
		{
			logErr("SQL Exception " + sqle.getMessage());
			throw new Exception("Call to isClosed is Failed!");
		}
		catch (Exception e)
		{
			logErr("Unexpected Exception " + e.getMessage());
			throw new Exception("Call to isClosed is Failed!", e);
		}
	}


	/*
	 * @testName:         testIsClosed02
	 *                    
	 * @assertion:        A Connection object represents a Connection in a database.  
	 *                    A Connection session includes the SQL Statements that are 
	 *                    executed and the results that are returned over that connection.
	 *                    (See section 11.1 of JDBC 2.0 API Reference & Tutorial second 
	 *                    edition).  
	 *                    
	 *                    The JDBC drivers must provide accurate and complete 
	 *                    metadata through the Connection.getMetaData() method. (See 
	 *                    section 6.2.2.3 Java2 Platform Enterprise Edition (J2EE) 
	 *                    specification v1.2)
	 *                    
	 *                    The isClosed method returns a boolean value; true if the 
	 *                    connection is closed or false if it is still open.
	 *                    (See JDK 1.2.2 API documentation)
	 *
	 * @test_Strategy:    Get a Connection object and call close() method
	 *                    and call isClosed() method
	 *                    It should return a boolean value and the value should be 
	 *                    equal to true
	 *
	 */
	@Test
	public void testIsClosed02() throws Exception 
	{
		boolean closeFlag=false;
		Connection con=null;
		try
		{
//			if(drManager.equals("yes"))
//			{
				DriverManagerConnection dmCon = new DriverManagerConnection();
				con = dmCon.getConnection(props);
//			}
//			else
//			{
//				DataSourceConnection dsCon = new DataSourceConnection();
//				con = dsCon.getConnection(props);
//			}
			
			// invoking the close method
			con.close();
			
			logMsg("Calling isClosed() method ");
			closeFlag= con.isClosed();
			
			if (closeFlag)
			{
				logMsg("isClosed method returns  "+ closeFlag);
			}
			else
			{
				logErr("isClosed method returns an invalid value");
				throw new Exception("Call to isClosed is Failed!");
			}
		}
		catch (SQLException sqle)
		{
			logErr("SQL Exception " + sqle.getMessage());
			throw new Exception("Call to isClosed is Failed!");
		}
		catch (Exception e)
		{
			logErr("Unexpected Exception " + e.getMessage());
			throw new Exception("Call to isClosed is Failed!", e);
		}
	}


	/*
	 * @testName:         testIsReadOnly
	 *                    
	 * @assertion:        A Connection object represents a Connection in a database.  
	 *                    A Connection session includes the SQL Statements that are 
	 *                    executed and the results that are returned over that connection.
	 *                    (See section 11.1 of JDBC 2.0 API Reference & Tutorial second 
	 *                    edition). 
	 *                    
	 *                    The JDBC drivers must provide accurate and complete 
	 *                    metadata through the Connection.getMetaData() method. (See 
	 *                    section 6.2.2.3 Java2 Platform Enterprise Edition (J2EE) 
	 *                    specification v1.2).  
	 *                    
	 *                    The isReadOnly method returns a boolean value; true if the 
	 *                    connection is in read-only mode and false otherwise.
	 *                    (See JDK 1.2.2 API documentation)
	 *
	 * @test_Strategy:    Get a Connection object and call setReadOnly(boolean b)
	 *                    method and call isReadOnly() method
	 *                    It should return a boolean value that is been set
	 *
	 */
	@Test
	public void testIsReadOnly() throws Exception 
	{
		boolean errorFlag=true;
		try
		{
//			logMsg("Testing in "+ sVehicle + " vehicle");
//					
//			if (sVehicle.equalsIgnoreCase("ejb"))
//			{
				// In case of EJB vehicle connection will be in a transaction and 
				// it wont be possible to set the ReadOnly property. If the api can
				// return a boolean it is successful.
//				boolean b = conn.isReadOnly();
//				errorFlag = false;						
//			}				
//			else
//			{
				logMsg("invoking the setReadOnly method");
				conn.setReadOnly(false);
				logMsg("Calling isReadOnly() method ");
				if(conn.isReadOnly())
				{
					errorFlag=true;
				}
				else
				{
					errorFlag=false;
				}											
//			}
			
			if (!errorFlag)
			{
				logMsg("isReadOnly method is Successful");
			}
			else
			{
				logErr("isReadOnly method returns an invalid value");
				throw new Exception("Call to isReadOnly is Failed!");
			}
		}
		catch (SQLException sqle)
		{
			logErr("SQL Exception " + sqle.getMessage());
			throw new Exception("Call to isReadOnly is Failed!");
		}
		catch (Exception e )
		{
			logErr("Unexpected Exception " + e.getMessage());
			throw new Exception("Call to isReadOnly is Failed!", e);
		}
	}


	/*
	 * @testName:         testNativeSQL
	 *                    
	 * @assertion:        A Connection object represents a Connection in a database.  
	 *                    A Connection session includes the SQL Statements that are 
	 *                    executed and the results that are returned over that connection.
	 *                    (See section 11.1 of JDBC 2.0 API Reference & Tutorial second 
	 *                    edition)
	 *                    
	 *                    The JDBC drivers must provide accurate and complete 
	 *                    metadata through the Connection.getMetaData() method. (See 
	 *                    section 6.2.2.3 Java2 Platform Enterprise Edition (J2EE) 
	 *                    specification v1.2).  
	 *                    
	 *                    The nativeSQL(String sql) method returns a String object 
	 *                    representing the native form of a sql.  (See JDK 1.2.2 API
	 *                    documentation)
	 *
	 * @test_Strategy:    Get a Connection object and call nativeSQL(String sql) method
	 *                    It should return a String value which represents native SQL
	 *                    grammar implementation of the SQL statement if the driver supports
	 *                    else it returns the actual SQL statement as a String.This is checked
	 *                   by using instanceof method
	 */
	@Test
	public void testNativeSQL() throws Exception 
	{
		String sSqlStmt=null;
		String nativeSql=null;
		try
		{
//			sSqlStmt=props.getProperty("Escape_Seq_Query","");
		    sSqlStmt = queryAll;
			logMsg("SQL Statement with Escape Syntax" + sSqlStmt);
			
			//invoking the nativeSQL method
			logMsg("Calling nativeSQL method ");
			nativeSql=conn.nativeSQL(sSqlStmt);
			
			if (nativeSql instanceof String)
			{
				logMsg("nativeSQL method returns :  " + nativeSql);
			}
			else
			{
				logErr("nativeSQL method does not return the System native SQL grammar");
				throw new Exception("Call to nativeSQL is Failed!");
			}
			
		}
		catch (SQLException sqle)
		{
			logErr("SQL Exception " + sqle.getMessage());
			throw new Exception("Call to nativeSQL is Failed!");
		}
		catch (Exception e )
		{
			logErr("Unexpected Exception " + e.getMessage());
			throw new Exception("Call to nativeSQL is Failed!", e);
		}
	}


	/* cleanup */
	@AfterClass
	public static void  cleanup() throws Exception	
	{
		try
		{
//			dbSch.destroyData(conn);
			// Close the Statement object
			stmt.close();
			// close the Database 
			rsSch.dbUnConnect(conn);
			logMsg("Cleanup ok;");
		}
		catch (Exception e)
		{
			logErr("An error occurred while closing the database connection");
		}
	}


}
